home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / GL / flight / sound.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  8KB  |  346 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17.  
  18. /*
  19.  *  flight/sound.c $Revision: 1.6 $
  20.  */
  21.  
  22. #ifdef AUDIO
  23.  
  24. #include <stdio.h>
  25. #include "stdlib.h"
  26. #include "math.h"
  27. #include "malloc.h"
  28. #include "audio.h"
  29. #include "aifflib.h"
  30. #include "sound.h"
  31. #include "flight.h"
  32.  
  33. static ALport    outport[MAXAUDIOPORT];
  34. static char    portname[5] = "out?",
  35.         soundpath[256], *soundfileptr;
  36. static short    num_open_ports = 0;
  37. static long    flightparams[2] = { AL_OUTPUT_RATE, AL_RATE_16000 },
  38.         oldparams[2] = { AL_OUTPUT_RATE, 0 };
  39.  
  40. static short    *audiobuf = 0;
  41. short        *misslesample = 0, *cannonsample = 0,
  42.         *diesample = 0, *locksample = 0;
  43. int        misslelength, cannonlength, dielength, locklength;
  44. static short    enginetype = 1, *explosionsample = 0, *jetthrust = 0,
  45.         *pitchthrust = 0, *propthrust = 0, *thrustsample;
  46. static int    explosionlength, jetthrustlength, propthrustlength,
  47.         thrustlength;
  48. short        sound_mode = 2;
  49.  
  50.  
  51.  
  52. void play_samps(short* buffer, int length)
  53. {
  54.     int    i, bestp, samps, smin;
  55.  
  56.     /*
  57.      *  don't play if no good buffers or sound_mode not set to play
  58.      */
  59.     if (!length || !num_open_ports || sound_mode == 0)
  60.     return;
  61.  
  62.     /*
  63.      *  find the most empty audio port
  64.      */
  65.     if (sound_mode == 2)
  66.     bestp = 1;
  67.     else
  68.     bestp = 0;
  69.     smin = ALgetfilled(outport[bestp]);
  70.     for (i = bestp+1; i < num_open_ports; i++)
  71.     {
  72.     samps = ALgetfilled(outport[i]);
  73.     if (samps == 0)
  74.     {
  75.         bestp = i;    /* empty, so use it */
  76.         break;
  77.     }
  78.     if (samps < smin)
  79.     {
  80.         smin = samps;
  81.         bestp = i;
  82.     }
  83.     }
  84.  
  85.     ALwritesamps(outport[bestp], buffer, length);
  86. }
  87.  
  88.  
  89. void play_explosion(float dist)
  90. {
  91.     int i;
  92.  
  93.     if (!explosionlength || dist <= 0.0)
  94.     return;
  95.     dist /= 5000000.0;
  96.     if (dist < 1.0)
  97.     dist = 1.0;
  98.     else
  99.     dist = 1.0/dist;
  100.  
  101.     /*
  102.      *  change amplitude by 1/distance**2
  103.      */
  104.     for (i = 0; i < explosionlength; i++)
  105.     audiobuf[i] = (short)(dist * (float)explosionsample[i]);
  106.  
  107.     /*
  108.      *  write samples
  109.      */
  110.     play_samps(audiobuf, explosionlength);
  111.  
  112. }
  113.  
  114.  
  115. void thrust_type(short engine)
  116. {
  117.     enginetype = (engine != 0);
  118. }
  119.  
  120.  
  121. void play_thrust(void)
  122. {
  123.     static int sampptr = 0;
  124.     static int old_thrustlength = 0;
  125.  
  126.     if (thrustlength != old_thrustlength)
  127.     {
  128.         sampptr = 0;
  129.     old_thrustlength = thrustlength;
  130.     }
  131.  
  132.     if (sound_mode != 2 || thrustlength == 0)
  133.     return;
  134.  
  135.     while (ALgetfilled(outport[0]) < 24000)
  136.     {
  137.     if (thrustlength - sampptr <= 24000)
  138.     {
  139.         ALwritesamps(outport[0], pitchthrust+sampptr, thrustlength-sampptr);
  140.         sampptr = 0;
  141.     }
  142.     else
  143.     {
  144.         ALwritesamps(outport[0], pitchthrust+sampptr, 24000);
  145.         sampptr += 24000;
  146.     }
  147.     }
  148. }
  149.  
  150.  
  151. void pitch_thrust(float pitch)
  152. {
  153.     int i, index;
  154.     float findex, step, vol;
  155.  
  156.     if (num_open_ports == 0 || !pitchthrust)
  157.     return;
  158.  
  159.     play_thrust();        /* avoid pauses in sound */
  160.  
  161.     if (pitch == 0.0)
  162.     {
  163.     thrustlength = 0;
  164.     return;
  165.     }
  166.     if (enginetype)
  167.     {
  168.     thrustlength = jetthrustlength;
  169.     thrustsample = jetthrust;
  170.     }
  171.     else
  172.     {
  173.     thrustlength = propthrustlength;
  174.     thrustsample = propthrust;
  175.     }
  176.     step = 4.0 - 3.0*pitch;
  177.     vol = 1.0 + pitch;
  178.     thrustlength = (int)((float)thrustlength * step);
  179.     thrustlength &= ~1;
  180.     step = 2.0/step;
  181.     for (findex = 0.0, i = 0; i < thrustlength; i+=2)
  182.     {
  183.     index = (int)findex & ~1;
  184.     findex += step;
  185.     pitchthrust[i] = thrustsample[index] * vol;
  186.     pitchthrust[i+1] = thrustsample[index+1] * vol;
  187.     }
  188. }
  189.  
  190.  
  191. static int get_aiff_sound(char* filename, short** samplebuffer)
  192. {
  193.     AIFFfile    fd;
  194.     int        len;
  195.  
  196.     /*
  197.      *  build path name
  198.      */
  199.     strcpy(soundfileptr, filename);
  200.  
  201.     /*
  202.      *  open file, return no length on error
  203.      */
  204.     if ((fd = AIFFopen(soundpath, "r")) < 0)
  205.     {
  206.     if (strcmp("jthrust.aiff", filename) &&        /* XXX remove when */
  207.         strcmp("pthrust.aiff", filename))        /* good thrust files */
  208.     {                        /* exist */
  209.     fprintf(stderr, "Can't open \"%s\"\n", soundpath);
  210.     return 0;
  211.     }
  212.     }
  213.  
  214.     /*
  215.      *  get size of buffer (in samples) and malloc an array
  216.      */
  217.     len = AIFFgetlength(fd);
  218.     if (len <= 0)
  219.     {
  220.     AIFFclose(fd);
  221.     return 0;
  222.     }
  223.     *samplebuffer = (short *)malloc(len * 2 * sizeof(short));
  224.  
  225.     /*
  226.      *  read the samples, close the file, return the number of samples
  227.      */
  228.     len = AIFFread(fd, *samplebuffer, len);
  229.     AIFFclose(fd);
  230.     return len;
  231. }
  232.  
  233.  
  234. static void flightALerror(long errcode, const char* str, ...)
  235. {
  236.     /*
  237.      *  don't do anything, we just want to prevent errors getting displayed
  238.      */
  239. }
  240.  
  241.  
  242. void init_audio(void)
  243. {
  244.     AIFFfile fd;
  245.     ALconfig config;
  246.     char* path;
  247.     int i, pathlen;
  248.  
  249.     /*
  250.      *  return if not first call
  251.      */
  252.     if (num_open_ports)
  253.     return;
  254.  
  255.     /*
  256.      *  capture errors so user doesn't see them
  257.      */
  258.     ALseterrorhandler(flightALerror);
  259.  
  260.     config = ALnewconfig();
  261.     ALsetqueuesize(config, 64000);
  262.     ALsetchannels(config, AL_STEREO);
  263.     for (i = 0; i < MAXAUDIOPORT; i++)
  264.     {
  265.     portname[3] = '0' + num_open_ports;
  266.     outport[num_open_ports] = ALopenport(portname, "w", config);
  267.     if (outport[num_open_ports])
  268.         if (++num_open_ports == 10)        /* ten ports max */
  269.         break;
  270.     }
  271.  
  272.     /*
  273.      *  return if audio ports can't be opened.  if the machine
  274.      *  doesn't have audio capability we'll return here
  275.      */
  276.     if (num_open_ports == 0) return;
  277.  
  278.     ALgetparams(AL_DEFAULT_DEVICE, oldparams, 2);
  279.     ALsetparams(AL_DEFAULT_DEVICE, flightparams, 2);
  280.  
  281.     /*
  282.      *  get path for sound samples
  283.      */
  284.     path = getenv("FLIGHTSOUND");
  285.  
  286.     if (!path || (pathlen = strlen(path)) > 240)
  287.     {
  288.     /*
  289.      *  no path or path too long
  290.      *  use default directory
  291.      */
  292.     strcpy(soundpath, sounddir);
  293.     soundfileptr = soundpath + strlen(soundpath);
  294.     }
  295.     else
  296.     {
  297.     strcpy(soundpath, path);        /* copy path */
  298.     if (soundpath[pathlen-1] != '/')    /* only one trailing / */
  299.         soundpath[pathlen++] = '/';
  300.     soundfileptr = soundpath + pathlen;
  301.     *soundfileptr = 0;
  302.     }
  303.  
  304.     if (!cannonsample)
  305.     cannonlength = get_aiff_sound("cannon.aiff", &cannonsample);
  306.     if (!diesample)
  307.     dielength = get_aiff_sound("die.aiff", &diesample);
  308.     if (!explosionsample)
  309.     explosionlength = get_aiff_sound("explosion.aiff", &explosionsample);
  310.     if (!locksample)
  311.     locklength = get_aiff_sound("lock.aiff", &locksample);
  312.     if (!misslesample)
  313.     misslelength = get_aiff_sound("missle.aiff", &misslesample);
  314.     if (!jetthrust)
  315.     jetthrustlength = get_aiff_sound("jthrust.aiff", &jetthrust);
  316.     if (!propthrust)
  317.     propthrustlength = get_aiff_sound("pthrust.aiff", &propthrust);
  318.  
  319.     /*
  320.      *  make buffer to hold pitch shifted thrust sound
  321.      */
  322.     if (propthrustlength > jetthrustlength)
  323.     pitchthrust = (short *)malloc(4 * propthrustlength * 2 * sizeof(short));
  324.     else if (jetthrustlength > 0)
  325.     pitchthrust = (short *)malloc(4 * jetthrustlength * 2 * sizeof(short));
  326.     else
  327.     pitchthrust = 0;
  328.  
  329.     if (explosionlength > 0 && !audiobuf)
  330.     audiobuf = (short *)malloc(explosionlength * 2 * sizeof( short));
  331.     else
  332.     audiobuf = 0;
  333. }
  334.  
  335.  
  336. void    close_audio(void)
  337. {
  338.     int i;
  339.  
  340.     ALsetparams (AL_DEFAULT_DEVICE, oldparams, 2);
  341.     for (i = 0; i < num_open_ports; i++)
  342.     ALcloseport(outport[i]);
  343. }
  344.  
  345. #endif
  346.